home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gstype1.c < prev    next >
C/C++ Source or Header  |  1997-03-29  |  16KB  |  583 lines

  1. /* Copyright (C) 1990, 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gstype1.c */
  20. /* Adobe Type 1 charstring interpreter */
  21. #include "math_.h"
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gsstruct.h"
  26. #include "gxarith.h"
  27. #include "gxfixed.h"
  28. #include "gxmatrix.h"
  29. #include "gxcoord.h"
  30. #include "gxistate.h"
  31. #include "gzpath.h"
  32. #include "gxchar.h"
  33. #include "gxfont.h"
  34. #include "gxfont1.h"
  35. #include "gxtype1.h"
  36.  
  37. /* Define whether to always do Flex segments as curves. */
  38. /* This is only an issue because some old Adobe DPS fonts */
  39. /* seem to violate the Flex specification in a way that requires this. */
  40. #define ALWAYS_DO_FLEX_AS_CURVE 1
  41.  
  42. /* ------ Main interpreter ------ */
  43.  
  44. /* Define a pointer to the charstring interpreter stack. */
  45. typedef fixed _ss *cs_ptr;
  46.  
  47. /*
  48.  * Continue interpreting a Type 1 charstring.  If str != 0, it is taken as
  49.  * the byte string to interpret.  Return 0 on successful completion, <0 on
  50.  * error, or >0 when client intervention is required (or allowed).  The int*
  51.  * argument is where the othersubr # is stored for callothersubr.
  52.  */
  53. private int
  54. gs_type1_charstring_interpret(gs_type1_state *pcis,
  55.   const gs_const_string *str, int *pindex)
  56. {    gs_font_type1 *pfont = pcis->pfont;
  57.     gs_type1_data *pdata = &pfont->data;
  58.     bool encrypted = pdata->lenIV >= 0;
  59.     gs_op1_state s;
  60.     fixed cstack[ostack_size];
  61. #define cs0 cstack[0]
  62. #define ics0 fixed2int_var(cs0)
  63. #define cs1 cstack[1]
  64. #define ics1 fixed2int_var(cs1)
  65. #define cs2 cstack[2]
  66. #define ics2 fixed2int_var(cs2)
  67. #define cs3 cstack[3]
  68. #define ics3 fixed2int_var(cs3)
  69. #define cs4 cstack[4]
  70. #define ics4 fixed2int_var(cs4)
  71. #define cs5 cstack[5]
  72. #define ics5 fixed2int_var(cs5)
  73.     cs_ptr csp;
  74. #define clear csp = cstack - 1
  75.     ip_state *ipsp = &pcis->ipstack[pcis->ips_count - 1];
  76.     register const byte *cip;
  77.     register crypt_state state;
  78.     register int c;
  79.     int code = 0;
  80.     fixed ftx = pcis->origin.x, fty = pcis->origin.y;
  81.  
  82.     switch ( pcis->init_done )
  83.       {
  84.       case -1:
  85.         break;
  86.       case 0: 
  87.         gs_type1_finish_init(pcis, &s);  /* sets sfc, ptx, pty, origin */
  88.         ftx = pcis->origin.x, fty = pcis->origin.y;
  89.         break;
  90.       default /*case 1*/:
  91.         ptx = pcis->position.x;
  92.         pty = pcis->position.y;
  93.         sfc = pcis->fc;
  94.       }
  95.     sppath = pcis->path;
  96.     s.pcis = pcis;
  97.     init_cstack(cstack, csp, pcis);
  98.  
  99.     if ( str == 0 )
  100.       goto cont;
  101.     ipsp->char_string = *str;
  102.     cip = str->data;
  103. call:    state = crypt_charstring_seed;
  104.     if ( encrypted )
  105.        {    int skip = pdata->lenIV;
  106.         /* Skip initial random bytes */
  107.         for ( ; skip > 0; ++cip, --skip )
  108.           decrypt_skip_next(*cip, state);
  109.        }
  110.     goto top;
  111. cont:    cip = ipsp->ip;
  112.     state = ipsp->dstate;
  113. top:    for ( ; ; )
  114.      { uint c0 = *cip++;
  115.  
  116.        charstring_next(c0, state, c, encrypted);
  117.        if ( c >= c_num1 )
  118.          {
  119.            /* This is a number, decode it and push it on the stack. */
  120.  
  121.            if ( c < c_pos2_0 )
  122.          {                /* 1-byte number */
  123.            decode_push_num1(csp, c);
  124.          }
  125.            else if ( c < cx_num4 )
  126.          {                /* 2-byte number */
  127.            decode_push_num2(csp, c, cip, state, encrypted);
  128.          }
  129.            else if ( c == cx_num4 )
  130.          {                /* 4-byte number */
  131.            long lw;
  132.  
  133.            decode_num4(lw, cip, state, encrypted);
  134.            *++csp = int2fixed(lw);
  135.            if ( lw != fixed2long(*csp) )
  136.              return_error(gs_error_rangecheck);
  137.          }
  138.            else            /* not possible */
  139.          return_error(gs_error_invalidfont);
  140. pushed:           if_debug3('1', "[1]%d: (%d) %f\n",
  141.              (int)(csp - cstack), c, fixed2float(*csp));
  142.            continue;
  143.          }
  144.  
  145. #ifdef DEBUG
  146.        if ( gs_debug['1'] )
  147.          { static const char *c1names[] =
  148.             { char1_command_names };
  149.            if ( c1names[c] == 0 )
  150.          dprintf2("[1]0x%lx: %02x??\n", (ulong)(cip - 1), c);
  151.            else
  152.          dprintf3("[1]0x%lx: %02x %s\n", (ulong)(cip - 1), c,
  153.               c1names[c]);
  154.          }
  155. #endif
  156.        switch ( (char_command)c )
  157.          {
  158. #define cnext clear; goto top
  159. #define inext goto top
  160.  
  161.         /* Commands with identical functions in Type 1 and Type 2, */
  162.         /* except for 'escape'. */
  163.  
  164.     case c_undef0:
  165.     case c_undef2:
  166.     case c_undef17:
  167.         return_error(gs_error_invalidfont);
  168.     case c_callsubr:
  169.         c = fixed2int_var(*csp) + pdata->subroutineNumberBias;
  170.         code = (*pdata->subr_proc)
  171.           (pfont, c, false, &ipsp[1].char_string);
  172.         if ( code < 0 )
  173.           return_error(code);
  174.         --csp;
  175.         ipsp->ip = cip, ipsp->dstate = state;
  176.         ++ipsp;
  177.         cip = ipsp->char_string.data;
  178.         goto call;
  179.     case c_return:
  180.         --ipsp;
  181.         goto cont;
  182.     case c_undoc15:
  183.         /* See gstype1.h for information on this opcode. */
  184.         cnext;
  185.         
  186.         /* Commands with similar but not identical functions */
  187.         /* in Type 1 and Type 2 charstrings. */
  188.  
  189.     case cx_hstem:
  190.         apply_path_hints(pcis, false);
  191.         type1_hstem(pcis, cs0, cs1);
  192.         cnext;
  193.     case cx_vstem:
  194.         apply_path_hints(pcis, false);
  195.         type1_vstem(pcis, cs0, cs1);
  196.         cnext;
  197.     case cx_vmoveto:
  198.         cs1 = cs0;
  199.         cs0 = 0;
  200.         accum_y(cs1);
  201. move:        /* cs0 = dx, cs1 = dy for hint checking. */
  202.         if ( (pcis->hint_next != 0 || path_is_drawing(sppath)) &&
  203.              pcis->flex_count == flex_max
  204.            )
  205.           apply_path_hints(pcis, true);
  206.         code = gx_path_add_point(sppath, ptx, pty);
  207.         goto cc;
  208.     case cx_rlineto:
  209.         accum_xy(cs0, cs1);
  210. line:        /* cs0 = dx, cs1 = dy for hint checking. */
  211.         code = gx_path_add_line(sppath, ptx, pty);
  212. cc:        if ( code < 0 )
  213.           return code;
  214. pp:        if_debug2('1', "[1]pt=(%g,%g)\n",
  215.               fixed2float(ptx), fixed2float(pty));
  216.         cnext;
  217.     case cx_hlineto:
  218.         accum_x(cs0);
  219.         cs1 = 0;
  220.         goto line;
  221.     case cx_vlineto:
  222.         cs1 = cs0;
  223.         cs0 = 0;
  224.         accum_y(cs1);
  225.         goto line;
  226.     case cx_rrcurveto:
  227.         code = gs_op1_rrcurveto(&s, cs0, cs1, cs2, cs3, cs4, cs5);
  228.         goto cc;
  229.     case cx_endchar:
  230.         if ( pcis->seac_base >= 0 )
  231.            {    /* We just finished the accent of a seac. */
  232.             /* Do the base character. */
  233.             gs_const_string bstr;
  234.             int bchar = pcis->seac_base;
  235.             pcis->seac_base = -1;
  236.             /* Restore the coordinate system origin */
  237.             pcis->asb_diff = pcis->adxy.x = pcis->adxy.y = 0;
  238.             sppath->position.x = pcis->position.x = ftx;
  239.             sppath->position.y = pcis->position.y = fty;
  240.             pcis->os_count = 0;    /* clear */
  241.             /* Clear the ipstack, in case the accent ended */
  242.             /* inside a subroutine. */
  243.             pcis->ips_count = 1;
  244.             /* Remove any accent hints. */
  245.             reset_stem_hints(pcis);
  246.             /* Ask the caller to provide a new string. */
  247.             code = (*pdata->seac_proc)(pfont, bchar, &bstr);
  248.             if ( code != 0 )
  249.               {    *pindex = bchar;
  250.                 return code;
  251.               }
  252.             /* Continue with the supplied string. */
  253.             clear;
  254.             ptx = ftx, pty = fty;
  255.             ipsp = &pcis->ipstack[0];
  256.             ipsp->char_string = bstr;
  257.             cip = bstr.data;
  258.             goto call;
  259.           }
  260.         /* This is a real endchar.  Handle it below. */
  261.         return gs_type1_endchar(pcis);
  262.     case cx_rmoveto:
  263.         accum_xy(cs0, cs1);
  264.         goto move;
  265.     case cx_hmoveto:
  266.         accum_x(cs0);
  267.         cs1 = 0;
  268.         goto move;
  269.     case cx_vhcurveto:
  270.       {    gs_fixed_point pt1, pt2;
  271.         fixed ax0 = sppath->position.x - ptx;
  272.         fixed ay0 = sppath->position.y - pty;
  273.         accum_y(cs0);
  274.         pt1.x = ptx + ax0, pt1.y = pty + ay0;
  275.         accum_xy(cs1, cs2);
  276.         pt2.x = ptx, pt2.y = pty;
  277.         accum_x(cs3);
  278.         code = gx_path_add_curve(sppath, pt1.x, pt1.y, pt2.x, pt2.y, ptx, pty);
  279.       }    goto cc;
  280.     case cx_hvcurveto:
  281.       {    gs_fixed_point pt1, pt2;
  282.         fixed ax0 = sppath->position.x - ptx;
  283.         fixed ay0 = sppath->position.y - pty;
  284.         accum_x(cs0);
  285.         pt1.x = ptx + ax0, pt1.y = pty + ay0;
  286.         accum_xy(cs1, cs2);
  287.         pt2.x = ptx, pt2.y = pty;
  288.         accum_y(cs3);
  289.         code =  gx_path_add_curve(sppath, pt1.x, pt1.y, pt2.x, pt2.y, ptx, pty);
  290.       }    goto cc;
  291.  
  292.         /* Commands only recognized in Type 1 charstrings, */
  293.         /* plus 'escape'. */
  294.  
  295.     case c1_closepath:
  296.         code = gs_op1_closepath(&s);
  297.         apply_path_hints(pcis, true);
  298.         goto cc;
  299.     case c1_hsbw:
  300.         gs_type1_sbw(pcis, cs0, fixed_0, cs1, fixed_0);
  301. rsbw:        /* Give the caller the opportunity to intervene. */
  302.         pcis->os_count = 0;    /* clear */
  303.         ipsp->ip = cip, ipsp->dstate = state;
  304.         pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
  305.         /* If we aren't in a seac, do nothing else now; */
  306.         /* finish_init will take care of the rest. */
  307.         if ( pcis->init_done < 0 )
  308.           {    /* Finish init when we return. */
  309.             pcis->init_done = 0;
  310.           }
  311.         else
  312.           {    /* Do accumulate the side bearing now. */
  313.             accum_xy(pcis->lsb.x, pcis->lsb.y);
  314.             pcis->position.x = ptx;
  315.             pcis->position.y = pty;
  316.           }
  317.         return type1_result_sbw;
  318.     case cx_escape:
  319.         charstring_next(*cip, state, c, encrypted); ++cip;
  320. #ifdef DEBUG
  321.         if ( gs_debug['1'] && c < char1_extended_command_count )
  322.           { static const char *ce1names[] =
  323.              { char1_extended_command_names };
  324.             if ( ce1names[c] == 0 )
  325.               dprintf2("[1]0x%lx: %02x??\n", (ulong)(cip - 1), c);
  326.             else
  327.               dprintf3("[1]0x%lx: %02x %s\n", (ulong)(cip - 1), c,
  328.                    ce1names[c]);
  329.           }
  330. #endif
  331.         switch ( (char1_extended_command)c )
  332.            {
  333.         case ce1_dotsection:
  334.             pcis->dotsection_flag ^=
  335.               (dotsection_in ^ dotsection_out);
  336.             cnext;
  337.         case ce1_vstem3:
  338.             apply_path_hints(pcis, false);
  339.             if ( !pcis->vstem3_set && pcis->fh.use_x_hints )
  340.             {    center_vstem(pcis, pcis->lsb.x + cs2, cs3);
  341.                 /* Adjust the current point */
  342.                 /* (center_vstem handles everything else). */
  343.                 ptx += pcis->vs_offset.x;
  344.                 pty += pcis->vs_offset.y;
  345.                 pcis->vstem3_set = true;
  346.             }
  347.             type1_vstem(pcis, cs0, cs1);
  348.             type1_vstem(pcis, cs2, cs3);
  349.             type1_vstem(pcis, cs4, cs5);
  350.             cnext;
  351.         case ce1_hstem3:
  352.             apply_path_hints(pcis, false);
  353.             type1_hstem(pcis, cs0, cs1);
  354.             type1_hstem(pcis, cs2, cs3);
  355.             type1_hstem(pcis, cs4, cs5);
  356.             cnext;
  357.         case ce1_seac:
  358.           {    gs_const_string acstr;
  359.             /* Do the accent now.  When it finishes */
  360.             /* (detected in endchar), do the base character. */
  361.             pcis->seac_base = ics3;
  362.             /* Adjust the origin of the coordinate system */
  363.             /* for the accent (endchar puts it back). */
  364.             ptx = ftx, pty = fty;
  365.             pcis->asb_diff = cs0 - pcis->lsb.x;
  366.             pcis->adxy.x = cs1;
  367.             pcis->adxy.y = cs2;
  368.             accum_xy(cs1, cs2);
  369.             sppath->position.x = pcis->position.x = ptx;
  370.             sppath->position.y = pcis->position.y = pty;
  371.             pcis->os_count = 0;    /* clear */
  372.             /* Ask the caller to provide a new string. */
  373.             code = (*pdata->seac_proc)(pfont, ics4, &acstr);
  374.             if ( code != 0 )
  375.               {    *pindex = ics4;
  376.                 return code;
  377.               }
  378.             /* Continue with the supplied string. */
  379.             clear;
  380.             ipsp->char_string = acstr;
  381.             cip = acstr.data;
  382.             goto call;
  383.           }
  384.         case ce1_sbw:
  385.             gs_type1_sbw(pcis, cs0, cs1, cs2, cs3);
  386.             goto rsbw;
  387.         case ce1_div:
  388.             csp[-1] = float2fixed((float)csp[-1] / (float)*csp);
  389.             --csp; goto pushed;
  390.         case ce1_undoc15:
  391.             /* See gstype1.h for information on this opcode. */
  392.             cnext;
  393.         case ce1_callothersubr:
  394.           {    int num_results;
  395. #define fpts pcis->flex_points
  396.             /* We must remember to pop both the othersubr # */
  397.             /* and the argument count off the stack. */
  398.             switch ( *pindex = fixed2int_var(*csp) )
  399.             {
  400.             case 0:
  401.             {    /* We have to do something really sleazy */
  402.                 /* here, namely, make it look as though */
  403.                 /* the rmovetos never really happened, */
  404.                 /* because we don't want to interrupt */
  405.                 /* the current subpath. */
  406.                 gs_fixed_point ept;
  407. #if defined(DEBUG) || !ALWAYS_DO_FLEX_AS_CURVE
  408.                 fixed fheight = csp[-4];
  409. #endif
  410.                 gs_fixed_point hpt;
  411.  
  412.                 if ( pcis->flex_count != 8 )
  413.                   return_error(gs_error_invalidfont);
  414.                 /* Assume the next two opcodes */
  415.                 /* are `pop' `pop'.  Unfortunately, some */
  416.                 /* Monotype fonts put these in a Subr, */
  417.                 /* so we can't just look ahead in the */
  418.                 /* opcode stream. */
  419.                 pcis->ignore_pops = 2;
  420.                 csp[-4] = csp[-3] - pcis->asb_diff;
  421.                 csp[-3] = csp[-2];
  422.                 csp -= 3;
  423.                 gx_path_current_point(sppath, &ept);
  424.                 gx_path_add_point(sppath, fpts[0].x, fpts[0].y);
  425.                 sppath->state_flags =    /* <--- sleaze */
  426.                   pcis->flex_path_state_flags;
  427.                 /* Decide whether to do the flex as a curve. */
  428.                 hpt.x = fpts[1].x - fpts[4].x;
  429.                 hpt.y = fpts[1].y - fpts[4].y;
  430.                 if_debug3('1',
  431.                       "[1]flex: d=(%g,%g), height=%g\n",
  432.                       fixed2float(hpt.x), fixed2float(hpt.y),
  433.                       fixed2float(fheight) / 100);
  434. #if !ALWAYS_DO_FLEX_AS_CURVE            /* See beginning of file. */
  435.                 if ( any_abs(hpt.x) + any_abs(hpt.y) <
  436.                      fheight / 100
  437.                    )
  438.                 {    /* Do the flex as a line. */
  439.                     code = gx_path_add_line(sppath,
  440.                                 ept.x, ept.y);
  441.                 }
  442.                 else
  443. #endif
  444.                 {    /* Do the flex as a curve. */
  445.                     code = gx_path_add_curve(sppath,
  446.                         fpts[2].x, fpts[2].y,
  447.                         fpts[3].x, fpts[3].y,
  448.                         fpts[4].x, fpts[4].y);
  449.                     if ( code < 0 )
  450.                       return code;
  451.                     code = gx_path_add_curve(sppath,
  452.                         fpts[5].x, fpts[5].y,
  453.                         fpts[6].x, fpts[6].y,
  454.                         fpts[7].x, fpts[7].y);
  455.                 }
  456.             }
  457.                 if ( code < 0 )
  458.                   return code;
  459.                 pcis->flex_count = flex_max;    /* not inside flex */
  460.                 inext;
  461.             case 1:
  462.                 gx_path_current_point(sppath, &fpts[0]);
  463.                 pcis->flex_path_state_flags = /* <--- more sleaze */
  464.                   sppath->state_flags;
  465.                 pcis->flex_count = 1;
  466.                 csp -= 2;
  467.                 inext;
  468.             case 2:
  469.                 if ( pcis->flex_count >= flex_max )
  470.                   return_error(gs_error_invalidfont);
  471.                 gx_path_current_point(sppath,
  472.                         &fpts[pcis->flex_count++]);
  473.                 csp -= 2;
  474.                 inext;
  475.             case 3:
  476.                 /* Assume the next opcode is a `pop'. */
  477.                 /* See above as to why we don't just */
  478.                 /* look ahead in the opcode stream. */
  479.                 pcis->ignore_pops = 1;
  480.                 replace_stem_hints(pcis);
  481.                 csp -= 2;
  482.                 inext;
  483.             case 14:
  484.                 num_results = 1;
  485. blend:              {    int num_values = fixed2int_var(csp[-1]);
  486.                 int k1 = num_values / num_results - 1;
  487.                 int i, j;
  488.                 cs_ptr base, deltas;
  489.  
  490.                 if ( num_values < num_results ||
  491.                      num_values % num_results != 0
  492.                    )
  493.                   return_error(gs_error_invalidfont);
  494.                 base = csp - 1 - num_values;
  495.                 deltas = base + num_results - 1;
  496.                 for ( j = 0; j < num_results;
  497.                      j++, base++, deltas += k1
  498.                     )
  499.                   for ( i = 1; i <= k1; i++ )
  500.                     *base += deltas[i] *
  501.                       pdata->WeightVector.values[i];
  502.                 csp = base - 1;
  503.               }
  504.                 pcis->ignore_pops = num_results;
  505.                 inext;
  506.             case 15:
  507.                 num_results = 2;
  508.                 goto blend;
  509.             case 16:
  510.                 num_results = 3;
  511.                 goto blend;
  512.             case 17:
  513.                 num_results = 4;
  514.                 goto blend;
  515.             case 18:
  516.                 num_results = 6;
  517.                 goto blend;
  518.             }
  519.           }
  520. #undef fpts
  521.             /* Not a recognized othersubr, */
  522.             /* let the client handle it. */
  523.         {    int scount = csp - cstack;
  524.             int n;
  525.             /* Copy the arguments to the caller's stack. */
  526.             if ( scount < 1 || csp[-1] < 0 ||
  527.                  csp[-1] > int2fixed(scount - 1)
  528.                )
  529.               return_error(gs_error_invalidfont);
  530.             n = fixed2int_var(csp[-1]);
  531.             code = (*pdata->push_proc)(pfont, csp - (n + 1), n);
  532.             if ( code < 0 )
  533.               return_error(code);
  534.             scount -= n + 1;
  535.             pcis->position.x = ptx;
  536.             pcis->position.y = pty;
  537.             apply_path_hints(pcis, false);
  538.             /* Exit to caller */
  539.             ipsp->ip = cip, ipsp->dstate = state;
  540.             pcis->os_count = scount;
  541.             pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
  542.             if ( scount )
  543.               memcpy(pcis->ostack, cstack, scount * sizeof(fixed));
  544.             return type1_result_callothersubr;
  545.         }
  546.         case ce1_pop:
  547.             /* Check whether we're ignoring the pops after */
  548.             /* a known othersubr. */
  549.             if ( pcis->ignore_pops != 0 )
  550.               {    pcis->ignore_pops--;
  551.                 inext;
  552.               }
  553.             ++csp;
  554.             code = (*pdata->pop_proc)(pfont, csp);
  555.             if ( code < 0 )
  556.               return_error(code);
  557.             goto pushed;
  558.         case ce1_setcurrentpoint:
  559.             ptx = ftx, pty = fty;
  560.             cs0 += pcis->adxy.x;
  561.             cs1 += pcis->adxy.y;
  562.             accum_xy(cs0, cs1);
  563.             goto pp;
  564.         default:
  565.             return_error(gs_error_invalidfont);
  566.            }
  567.         /*NOTREACHED*/
  568.  
  569.         /* Fill up the dispatch up to 32. */
  570.  
  571.     case_c1_undefs:
  572.     default:        /* pacify compiler */
  573.         return_error(gs_error_invalidfont);
  574.          }
  575.      }
  576. }
  577.  
  578. /* Register the interpreter. */
  579. void
  580. gs_gstype1_init(gs_memory_t *mem)
  581. {    gs_charstring_interpreter[1] = gs_type1_charstring_interpret;
  582. }
  583.